
#ifndef FONTDEFINITION_H
#define FONTDEFINITION_H

#include "StringUtil.h"
#include <map>
#include <vector>

/** @class FontDefinition
    Defines the data necessary for font generation.
*/
class FontDefinition
{
public:
    StringUtil::String  mFontName;
    StringUtil::String  mFontFileName;
    bool            mIsBold;
    bool            mIsUnderline;
    bool            mIsItalic;
    size_t          mFontHeight;
    size_t          mFontWidth;
    size_t          mStartCharacter;
    size_t          mImageWidth;
    size_t          mImageHeight;
    size_t          mCellWidth;
    size_t          mCellHeight;

    enum AntiAliasMode
    {
        None,
        Normal
    };
    AntiAliasMode   mAntiAliasMode;

public:
};

/** @class FontMap
    A singleton class which loads all system fonts, and creates a mapping
    between the font name and the font file.
*/
class FontMap
{
private:
    static FontMap* mInstance;      ///< Single instance of the class
    bool    mIsValid;               ///< Indicates if the settings are valid
    FontMap();

    /** @class FontItem
        Stores information about the font files for each font.

        Each family name (Arial, Times New Roman, etc.) can have variations,
        such as bold, italic, and bold italic.  These are each in a separate
        file, but we want to group them together (then allow the styles to be
        applied.)  The FontItem structure stores the family name (which is the
        key for the font map) and the names of each file.  By default, each file
        name is the empty string, so if a style does not exist for a given font,
        we can still use it.  For example, if a font does not have a regular
        style (unlikely) but it does have a bold style, we can still use bold.
        A selected style that is not present will just go to the next available
        style.
    */
    class FontItem
    {
    private:
        enum FONT_STYLE { REGULAR = 0, BOLD = 1, ITALIC = 2, BOLD_ITALIC = 3, STYLE_COUNT };

        StringUtil::String mFamilyName;   ///< Family name of the font
        std::vector< StringUtil::String > mFileNames;  ///< Name of the font files.  The FONT_STYLE enumeration is used to index the file name.

    public:
        /** Constructor */
        FontItem( const StringUtil::String& fontName = "" );

        /** Get the family name of the font */
        StringUtil::String GetFamilyName() const;

        /** Associate a file name with this font with specified stylizations */
        bool SetFontFile( const StringUtil::String& fileName, bool isBold, bool isItalic, bool replaceIfPresent = false );
        /** Get the name of the font file with the specified stylizations */
        StringUtil::String GetFontFile( bool isBold, bool isItalic ) const;
    };

    typedef std::map< StringUtil::String, FontItem > FontMapType;
    FontMapType         mFontMap;   ///< Map associating the font face name with the file name
    FontMapType::const_iterator mMapIterator;   /// Used for iterating over the map

public:
    typedef FontMapType::const_iterator ConstIterator;
    typedef FontMapType::iterator       Iterator;

    /** Get the iterator at the front of the map */
    Iterator Begin();
    /** Get the iterator at the front of the map */
    ConstIterator Begin() const;
    /** Get the iterator at the end of the map */
    Iterator End();
    /** Get the iterator at the end of the map */
    ConstIterator End() const;

    /** Get the number of fonts in the map */
    size_t Count() const;

    /** Find an item in the map */
    Iterator Find( const StringUtil::String& key );
    /** Find an item in the map */
    ConstIterator Find( const StringUtil::String& key ) const;

    /** Get the file name of a given font with specified stylizations */
    StringUtil::String GetFileName( const StringUtil::String& fontName, bool isBold, bool isItalic ) const;

    /** Add a file name to the map */
    bool AddFileName( const StringUtil::String& fontName, const StringUtil::String& fileName, bool isBold, bool isItalic );

public:
    ~FontMap();

    /** Get a reference to the configuration settings */
    static FontMap& GetInstance();

    /** Get a pointer to the configuration settings */
    static FontMap* GetInstancePtr();
};

#endif  // FONTDEFINITION_H
